package com.github.jspxnet.worktask.dao.impl;

import com.github.jspxnet.enums.RecycleEnumType;
import com.github.jspxnet.sioc.annotation.Bean;
import com.github.jspxnet.sober.Criteria;
import com.github.jspxnet.sober.criteria.expression.Expression;
import com.github.jspxnet.sober.criteria.projection.Projections;
import com.github.jspxnet.sober.jdbc.JdbcOperations;
import com.github.jspxnet.sober.ssql.SSqlExpression;
import com.github.jspxnet.txweb.annotation.Transaction;
import com.github.jspxnet.utils.ArrayUtil;
import com.github.jspxnet.utils.ObjectUtil;
import com.github.jspxnet.utils.StringUtil;
import com.github.jspxnet.worktask.dao.ConfWorkFlowDAO;
import com.github.jspxnet.worktask.env.JWorkTask;
import com.github.jspxnet.worktask.model.enums.FlowNodeEnumType;
import com.github.jspxnet.worktask.table.*;
import lombok.extern.slf4j.Slf4j;
import java.util.Date;
import java.util.List;

@Slf4j
@Bean(namespace = JWorkTask.namespace)
public class ConfWorkFlowDAOImpl extends JdbcOperations implements ConfWorkFlowDAO {

    /**
     * @param id id
     * @return 载入
     */
    @Override
    public ConfWorkFlow load(long id) {
        return super.load(ConfWorkFlow.class, id,true);
    }

    /**
     *
     * @param id id
     * @return 删除所有节点
     */
    @Transaction
    @Override
    public int delete(long id) {

        ConfWorkFlow confWorkFlow = super.load(ConfWorkFlow.class, id,true);
        if (confWorkFlow.getId()<=0)
        {
            return 0;
        }
        //删除节点
        createCriteria(ConfFlowJob.class).add(Expression.eq("namespace", confWorkFlow.getNamespace()))
                .add(Expression.eq("flowNo", confWorkFlow.getFlowNo())).delete(true);

        createCriteria(ConfWorkFlow.class).add(Expression.eq("namespace", confWorkFlow.getNamespace()))
                .add(Expression.eq("flowNo", confWorkFlow.getFlowNo())).delete(true);
        super.delete(DocumentFlowConf.class,"flowNo",confWorkFlow.getFlowNo());
        return super.delete(confWorkFlow);
    }


    /**
     *
     * @param flowNo 流程编号
     * @param namespace 命名空间
     * @return 流程配置
     */
    @Override
    public ConfWorkFlow getByFlowNo(String flowNo, String namespace) {
        Criteria criteria = createCriteria(ConfWorkFlow.class).add(Expression.eq("namespace", namespace));
        return criteria.add(Expression.eq("flowNo", flowNo)).objectUniqueResult(true);
    }

    /**
     * @param field      字段
     * @param find       查询字符串 "" 自动分开查询
     * @param term       条件
     * @param sortString 排序字符串
     * @param uid        用户id
     * @param page       页数
     * @param count      返回数量
     * @return 返回对象列表
     */
    @Override
    public List<ConfWorkFlow> getList(String[] field, String[] find, String namespace, String term, long uid, String sortString, int page, int count)  {
        if (StringUtil.isNull(sortString)) {
            sortString = "createDate:D";
        }
        Criteria criteria = createCriteria(ConfWorkFlow.class).add(Expression.eq("namespace", namespace));
        if (!ArrayUtil.isEmpty(find) && !ArrayUtil.isEmpty(field)) {
            criteria = criteria.add(Expression.find(field, find));
        }
        if (uid > 0) {
            criteria = criteria.add(Expression.eq("putUid", uid));
        }
        criteria = SSqlExpression.getTermExpression(criteria, term);
        return SSqlExpression.getSortOrder(criteria, sortString).setCurrentPage(page).setTotalCount(count).list(false);
    }

    /**
     *
     * @param flowNo 流程
     * @param namespace 命名空间
     * @param nodeId 节点
     * @return 得到下一步的节点配置
     */
    @Override
    public List<ConfFlowNode> getNextList(String flowNo, String namespace,String nodeId)  {
        Criteria criteria = createCriteria(ConfFlowNode.class).add(Expression.eq("namespace", namespace));
        criteria = criteria.add(Expression.eq("flowNo", flowNo));
        criteria = criteria.add(Expression.eq("parentNodeId", nodeId));
        return SSqlExpression.getSortOrder(criteria, "sortType:D").setCurrentPage(1).setTotalCount(10000).list(false);
    }

    /**
     *
     * @param flowNo 流程
     * @param namespace 命名空间
     * @param nodeId 节点
     * @return 得到要加入的节点列表
     */
    @Override
    public List<ConfFlowNode> getJoinConfFlowNode(String flowNo, String namespace, String nodeId)  {
        Criteria criteria = createCriteria(ConfFlowNode.class).add(Expression.eq("namespace", namespace));
        criteria = criteria.add(Expression.eq("flowNo", flowNo));
        criteria = criteria.add(Expression.eq("joinNodeId", nodeId));
        return SSqlExpression.getSortOrder(criteria, "sortType:D").setCurrentPage(1).setTotalCount(10000).list(false);
    }

    /**
     *
     * @param flowNo 流程
     * @param namespace 命名空间
     * @param nodeId 节点
     * @return  得到节点配置
     */
    @Override
    public ConfFlowNode getConfFlowNode(String flowNo, String namespace,String nodeId)  {
        Criteria criteria = createCriteria(ConfFlowNode.class).add(Expression.eq("namespace", namespace));
        criteria = criteria.add(Expression.eq("flowNo", flowNo));
        criteria = criteria.add(Expression.eq("nodeId", nodeId));
        return criteria.objectUniqueResult(true);
    }

    /**
     *
     * @param flowNo 流程
     * @param namespace 命名空间
     * @return 最后节点
     */
    @Override
    public ConfFlowNode finishConfFlowNode(String flowNo, String namespace)  {
        Criteria criteria = createCriteria(ConfFlowNode.class).add(Expression.eq("namespace", namespace));
        criteria = criteria.add(Expression.eq("flowNo", flowNo));
        criteria = criteria.add(Expression.eq("flowNodeType", FlowNodeEnumType.END.getValue()));
        return criteria.objectUniqueResult(true);
    }
    /**
     * @param field 字段
     * @param find  条件
     * @param term  条件表达式
     * @param uid   用户id
     * @return 得到记录条数
     */
    @Override
    public long getCount(String[] field, String[] find, String namespace, String term, long uid) {
        Criteria criteria = createCriteria(ConfWorkFlow.class);

        if (!StringUtil.isNull(namespace))
        {
            criteria = criteria.add(Expression.eq("namespace", namespace));
        }

        if (!ArrayUtil.isEmpty(find) && !ArrayUtil.isEmpty(field)) {
            criteria = criteria.add(Expression.find(field, find));
        }
        if (uid > 0) {
            criteria = criteria.add(Expression.eq("putUid", uid));
        }
        criteria = SSqlExpression.getTermExpression(criteria, term);
        return criteria.setProjection(Projections.rowCount()).longUniqueResult();
    }

    /**
     * @param ids id 列表
     * @return 放入回收站标识
     */
    @Override
    public boolean recycleType(String[] ids, RecycleEnumType recycleEnumType) {
        if (ArrayUtil.isEmpty(ids)) {
            return false;
        }
        List<ConfWorkFlow> workFlowList = createCriteria(ConfWorkFlow.class).add(Expression.in("id", ids)).
                setCurrentPage(1).setTotalCount(getMaxRows()).list(false);
        if (ObjectUtil.isEmpty(workFlowList))
        {
            return true;
        }
        try {
            for (ConfWorkFlow workFlow : workFlowList) {
                workFlow.setRecycleType(recycleEnumType.getValue());
                workFlow.setRecycleDate(new Date());
                super.update(workFlow,new String[]{"recycleType","recycleDate"});

            }
        } catch (Exception e) {
            log.error("",e);
            return false;
        }
        return true;
    }

    /**
     *
     * @param flowNo  流程
     * @param namespace 命名空间
     * @param nodeId 节点
     * @return 任务配置
     */
    @Override
    public ConfFlowJob getConfFlowJob(String flowNo, String namespace, String nodeId)
    {
        Criteria criteria =  createCriteria(ConfFlowJob.class).add(Expression.eq("namespace", namespace));
        criteria = criteria.add(Expression.eq("flowNo", flowNo));
        criteria = criteria.add(Expression.eq("nodeId", nodeId));
        return criteria.objectUniqueResult(false);
    }

    /**
     *
     * @param flowNo 流程
     * @param namespace 命名空间
     * @return 得到文档的独立配置
     */
    @Override
    public DocumentFlowConf getDocumentFlowConf(String flowNo, String namespace)
    {
        Criteria criteria =  createCriteria(DocumentFlowConf.class).add(Expression.eq("namespace", namespace));
        criteria = criteria.add(Expression.eq("flowNo", flowNo));
        return criteria.objectUniqueResult(false);
    }


    /**
     *
     * @param flowNo  流程
     * @param namespace 命名空间
     * @return 任务列表
     */
    @Override
    public List<ConfFlowJob> getConfFlowJobList(String flowNo, String namespace)
    {
        Criteria criteria =  createCriteria(ConfFlowJob.class).add(Expression.eq("namespace", namespace));
        criteria = criteria.add(Expression.eq("flowNo", flowNo));
        return criteria.setCurrentPage(1).setTotalCount(1000).list(true);
    }


}
